package leetcode

import (
	"fmt"
	"strconv"
	"strings"
	"unicode"
)

func checkRecord1(s string) bool {
	if strings.Count(s, "A") > 1 || strings.Contains(s, "LLL") {
		return false
	}
	return true
}

/** U(n,r) = n^r
 * n = 2 3*3 - !(condition)
 * n = 3 3*3*3 - !(condition) ALP LAP LPA | APL PAL PLA | ALL LAL LLA | APP PAP PPA | PLL LPL LLP | LPP PLP PPL | PPP
 LLL 1
	A ALP  AAL ALA LAA AAP APA PAA
	AAA 1

n = 4 3*3*3*3
	LLL AP  2*2
	LLLL
	AA ALP
	AAA ALP

n = 5 3*3*3*3*3
LLL AP U(2,2) * (n-3) LLLAP LLLAA LLLPA LLLPP
LLLLL 1
AA ALP
AAA ALP

n = 6 3*3*3*3*3
LLL AP U(2,n-3) * (n-3) = 8*3 = 24
LLLLLL 1
*/
func checkRecord2(n int) int {
	return 0
}

// Reverse reverses the input while respecting UTF8 encoding and combined characters
func Reverse(text string) string {
	textRunes := []rune(text)
	textRunesLength := len(textRunes)
	if textRunesLength <= 1 {
		return text
	}

	i, j := 0, 0
	for i < textRunesLength && j < textRunesLength {
		j = i + 1
		for j < textRunesLength && isMark(textRunes[j]) {
			j++
		}

		if isMark(textRunes[j-1]) {
			// Reverses Combined Characters
			reverse(textRunes[i:j], j-i)
		}

		i = j
	}

	// Reverses the entire array
	reverse(textRunes, textRunesLength)

	return string(textRunes)
}

func reverse(runes []rune, length int) {
	for i, j := 0, length-1; i < length/2; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}
}

// isMark determines whether the rune is a marker
func isMark(r rune) bool {
	return unicode.Is(unicode.Mn, r) || unicode.Is(unicode.Me, r) || unicode.Is(unicode.Mc, r)
}

// Reverse2 reverse a string
func Reverse2(s string) string {
	sbyte := []byte(s)
	len := len(s)
	for i := 0; i < len/2; i++ {
		tmp := sbyte[i]
		sbyte[i] = sbyte[len-1-i]
		sbyte[len-1-i] = tmp
	}

	if len < 32 {
		for i := 0; i < 32-len; i++ {
			sbyte = append(sbyte, '0')
		}
	}
	return string(sbyte)
}

// ReverseBits reverse a number
func ReverseBits(num uint32) uint32 {
	numstring := strconv.FormatUint(uint64(num), 2)
	rev := Reverse(numstring)
	fmt.Println(rev)

	decimal, err := strconv.ParseUint(rev, 2, 32)
	if err != nil {
		fmt.Println(err)
		return 0
	}
	return uint32(decimal)
}
